import { GoodResponse } from './../../../util/response';
import { RegisterPipe } from './../../../pipe/account/register.pipe';
import { LoginPipe } from './../../../pipe/account/login.pipe';
import { AdminService } from './../../../service/admin/admin.service';
import { ResponseInterceptor } from './../../../interceptor/response/response.interceptor';
import { ToolsService } from './../../../service/tools/tools.service';
import { Controller, Get, UseInterceptors, Request, Post, Body, UsePipes, BadRequestException, Response } from '@nestjs/common';
import * as joi from 'joi';
import * as bcrypt from 'bcrypt';
import config from '../../../config/config';
import * as jwt from 'jsonwebtoken';

const loginSchema: joi.ObjectSchema = joi.object().keys({
    username: joi
        .string()
        .pattern(/^[a-zA-Z0-9]{5,16}$/)
        .required(),
    password: joi
        .string()
        .pattern(/^[a-zA-Z0-9]{5,16}$/)
        .required(),
    captcha: joi
        .string()
        .pattern(/^[a-zA-Z0-9]{4}$/)
        .required(),
});
const registerSchema: joi.ObjectSchema = joi.object().keys({
    username: joi
        .string()
        .pattern(/^[a-zA-Z0-9]{5,16}$/)
        .required(),
    password: joi
        .string()
        .pattern(/^[a-zA-Z0-9]{5,16}$/)
        .required(),
    password_repeat: joi.ref('password'),
    captcha: joi
        .string()
        .pattern(/^[a-zA-Z0-9]{4}$/)
        .required(),
    sex: joi.number().default(1).min(0).max(2),
});
interface LoginProps {
    captcha: string;
    username: string;
    password: string;
}
interface RegisterProps {
    captcha: string;
    username: string;
    password: string;
    password_repeat: string;
    sex?: number;
}

@Controller(`${config.adminPath}/login`)
export class LoginController {
    constructor(private readonly toolsService: ToolsService, private readonly adminService: AdminService) {}
    @Get('code')
    index(@Request() req, @Response() res) {
        const currentCapture = this.toolsService.captcha();
        req.session.captchaText = currentCapture.text;
        res.type('image/svg+xml');
        res.send(currentCapture.data);
    }

    @UseInterceptors(ResponseInterceptor)
    @UsePipes(new LoginPipe(loginSchema))
    @Post()
    async login(@Body() body, @Request() req, @Response() res) {
        const { username, password, captcha }: LoginProps = body;
        if (!req.session.captchaText || captcha.toLowerCase() !== req.session.captchaText.toLowerCase())
            throw new BadRequestException('验证码错误');
        const user = await this.adminService.find(
            { username },
            { password: 1, username: 1, avatar: 1, role_id: 1, sex: 1, status: 1, email: 1, mobile: 1, is_super: 1 },
        );
        if (!user?.length) throw new BadRequestException('用户不存在');
        const isCorect = bcrypt.compareSync(password, user[0].password);
        if (!isCorect) throw new BadRequestException('密码错误');
        const token = jwt.sign({ _id: user[0]._id }, config.jwtSecret);
        res.cookie(config.authCookieKey, token, config.cookie);
        req.session.userInfo = user[0];
        res.send(GoodResponse(token));
    }

    @UseInterceptors(ResponseInterceptor)
    @UsePipes(new RegisterPipe(registerSchema))
    @Post('register')
    async register(@Body() body, @Request() req, @Response() res) {
        const { username, password, password_repeat, captcha, sex }: RegisterProps = body;
        if (!req.session.captchaText || captcha.toLowerCase() !== req.session.captchaText.toLowerCase())
            throw new BadRequestException('验证码错误');
        const previousUser = await this.adminService.find({ username });
        if (previousUser.length) throw new BadRequestException('用户名已存在');
        const userInfo: Partial<RegisterProps> = { username, password, password_repeat, captcha };
        if (sex !== undefined) userInfo.sex = sex;
        const user = await this.adminService.create(userInfo);
        const token = jwt.sign({ _id: user._id }, config.jwtSecret);
        res.cookie(config.authCookieKey, token, config.cookie);
        req.session.userInfo = user;
        res.send(GoodResponse(token));
    }

    @Post('logout')
    logout(@Response() res, @Request() req) {
        res.clearCookie(config.authCookieKey);
        req.session.userInfo = null;
        res.send(GoodResponse(undefined, '退出登录成功'));
    }

    @UseInterceptors(ResponseInterceptor)
    @Get('userInfo')
    async userInfo(@Request() req) {
        const userInfoForSession = req.session.userInfo;
        if (userInfoForSession) {
            return userInfoForSession;
        }
        const userInfo = await this.adminService.getUser(req);
        req.session.userInfo = userInfo;
        return userInfo;
    }

    @Get('getTestData')
    getCookie(@Request() req) {
        return req.session;
        // console.log(req.cookies);
        // return { cookies: req.cookies, signedCookies: req.signedCookies };

        // res.clearCookie(config.authCookieKey);
        // req.session.userInfo = null;
        // res.send(GoodResponse(undefined, '退出登录成功'));

        // res.send(res.locals.config);
    }
}
